<!DOCTYPE html>
<html lang="en"><head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.8.0 -->
<title>0014: Reacting to Mouse Events | gtkDcoding</title>
<meta name="generator" content="Jekyll v4.3.4" />
<meta property="og:title" content="0014: Reacting to Mouse Events" />
<meta name="author" content="Ron Tarrant" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Harnessing mouse events in a GTK Window - a D language tutorial." />
<meta property="og:description" content="Harnessing mouse events in a GTK Window - a D language tutorial." />
<link rel="canonical" href="http://localhost:4000/posts/0014-reacting-to-mouse-events.html" />
<meta property="og:url" content="http://localhost:4000/posts/0014-reacting-to-mouse-events.html" />
<meta property="og:site_name" content="gtkDcoding" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2019-03-01T00:00:00-05:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="0014: Reacting to Mouse Events" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"Ron Tarrant"},"dateModified":"2019-03-01T00:00:00-05:00","datePublished":"2019-03-01T00:00:00-05:00","description":"Harnessing mouse events in a GTK Window - a D language tutorial.","headline":"0014: Reacting to Mouse Events","mainEntityOfPage":{"@type":"WebPage","@id":"http://localhost:4000/posts/0014-reacting-to-mouse-events.html"},"url":"http://localhost:4000/posts/0014-reacting-to-mouse-events.html"}</script>
<!-- End Jekyll SEO tag -->
<link rel="stylesheet" href="../assets/main.css">
  <link rel="stylesheet" href="../css/style.css" /><link type="application/atom+xml" rel="alternate" href="http://localhost:4000/feed.xml" title="gtkDcoding" /></head>
<body><header class="site-header" role="banner">

  <div class="wrapper"><a class="site-title" rel="author" href="../">gtkDcoding</a><nav class="site-nav">
        <input type="checkbox" id="nav-trigger" class="nav-trigger" />
        <label for="nav-trigger">
          <span class="menu-icon">
            <svg viewBox="0 0 18 15" width="18px" height="15px">
              <path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
            </svg>
          </span>
        </label>

        <div class="trigger"><a class="page-link" href="../about.html">About</a><a class="page-link" href="../index-reverse.html">Posts in Date Order</a><a class="page-link" href="../topics.html">Blog Posts by Topic</a></div>
      </nav></div>
</header>
<main class="page-content" aria-label="Content">
      <div class="wrapper">
        <article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
	<header class="post-header">
		<link rel="stylesheet" href="../css/font_size.css" />
		<link rel="stylesheet" href="../css/figure.css" />
		<link rel="stylesheet" href="../css/topics/mouse.css" />  <!-- sub in the tag/topic -->
		<link rel="stylesheet" href="../css/modal.css" />
		<link rel="stylesheet" href="../css/post.css" />
		<link rel="stylesheet" href="../css/mascot_effects.css" />

		
		
		<p class="post-meta">
		<time class="dt-published" datetime="2019-03-01T00:00:00-05:00" itemprop="datePublished">Friday, March 1, 2019
		</time>• by <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span class="p-author h-card" itemprop="name">Ron Tarrant</span></span></p>
	</header>

	<div class="post-content e-content" itemprop="articleBody">
		<div class="skew-line"></div>
		<h1 id="0014-reacting-to-mouse-events">0014: Reacting to Mouse Events</h1>

<p>Now we start down the road toward full control of what happens when the user fiddles with mouse buttons. Sometimes we want to trigger something when a mouse button is pressed, but other times (more often, really) we want to react when the mouse button is released. This is the accepted norm in most GUI designs, so let’s not rock the boat until we have good reason to. And today, we have no excuse.</p>

<p>We’ve gone back to an unadorned <code class="language-plaintext highlighter-rouge">TestRigWindow</code> for this series of examples because this isn’t about <code class="language-plaintext highlighter-rouge">Button</code> buttons, it’s about mouse buttons. To avoid any possible confusion when I say ‘button,’ I don’t want any buttons in the GUI and that way I won’t get mixed up… and neither will you.</p>

<p>But since these examples—button press and button release—are so similar, we’ll talk about them both together.</p>

<h2 id="a-mouse-button-press-event">A Mouse Button Press Event</h2>

<div class="screenshot-frame">
	<div class="frame-header">
		Results of this example:
	</div>
	<div class="frame-screenshot">
		<figure>
			<img id="img0" src="../images/screenshots/005_mouse/mouse_01.png" alt="Current example output" />		<!-- img# -->
			
			<!-- Modal for screenshot -->
			<div id="modal0" class="modal">																	<!-- modal# -->
				<span class="close0">&times;</span>															<!-- close# -->
				<img class="modal-content" id="img00" />															<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal0");														// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img0");															// img#
			var modalImg = document.getElementById("img00");													// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close0")[0];											// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>
			<figcaption>
			Current example output
			</figcaption>
		</figure>
	</div>

	<div class="frame-terminal">
		<figure class="right">
			<img id="img1" src="../images/screenshots/005_mouse/mouse_01_term.png" alt="Current example terminal output" />		<!-- img#, filename -->

			<!-- Modal for terminal shot -->
			<div id="modal1" class="modal">																				<!-- modal# -->
				<span class="close1">&times;</span>																		<!-- close# -->
				<img class="modal-content" id="img11" />																		<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal1");																	// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img1");																		// img#
			var modalImg = document.getElementById("img11");																// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close1")[0];														// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>

			<figcaption>
				Current example terminal output (click for enlarged view)
			</figcaption>
		</figure>
	</div>

	<div class="frame-footer">																								<!-- ------------- filename (below) --------- -->
		The code file for this example is available <a href="https://github.com/rontarrant/gtkd_demos/blob/master/005_mouse/mouse_01_press.d" target="_blank">here</a>.
	</div>
</div>

<h2 id="and-a-mouse-button-release-event">And a Mouse Button Release Event</h2>

<div class="screenshot-frame">
	<div class="frame-header">
		Results of this example:
	</div>
	<div class="frame-screenshot">
		<figure>
			<img id="img2" src="../images/screenshots/005_mouse/mouse_02.png" alt="Current example output" />		<!-- img# -->
			
			<!-- Modal for screenshot -->
			<div id="modal2" class="modal">																<!-- modal# -->
				<span class="close2">&times;</span>														<!-- close# -->
				<img class="modal-content" id="img22" />														<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal2");													// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img2");														// img#
			var modalImg = document.getElementById("img22");												// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close2")[0];										// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>
			<figcaption>
			Current example output
			</figcaption>
		</figure>
	</div>

	<div class="frame-terminal">
		<figure class="right">
			<img id="img3" src="../images/screenshots/005_mouse/mouse_02_term.png" alt="Current example terminal output" /> 		<!-- img#, filename -->

			<!-- Modal for terminal shot -->
			<div id="modal3" class="modal">																			<!-- modal# -->
				<span class="close3">&times;</span>																	<!-- close# -->
				<img class="modal-content" id="img33" />																	<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal3");																// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img3");																	// img#
			var modalImg = document.getElementById("img33");															// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close3")[0];													// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>

			<figcaption>
				Current example terminal output (click for enlarged view)
			</figcaption>
		</figure>
	</div>

	<div class="frame-footer">																							<!--------- filename (below) ------------>
		The code file for this example is available <a href="https://github.com/rontarrant/gtkd_demos/blob/master/005_mouse/mouse_02_release.d" target="_blank">here</a>.
	</div>
</div>

<h2 id="a-new-import">A New Import</h2>

<p>Yeah, I’m not talking about this year’s Volvo or Toyota, but an import statement… this, to be exact:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="n">gdk</span><span class="p">.</span><span class="n">Event</span><span class="p">;</span>
</code></pre></div></div>

<p>We’ve seen the first one before, but I’ve included it here to remind everyone that it’s imported from the <code class="language-plaintext highlighter-rouge">gdk</code> side of things, not <code class="language-plaintext highlighter-rouge">gtk</code>.</p>

<p>Just below that import statement is a comment to let you know where we find <code class="language-plaintext highlighter-rouge">EventType</code> flags for events like:</p>

<ul>
  <li>buttons being pressed,</li>
  <li>buttons being released,</li>
  <li>the motion of the mouse pointer,</li>
  <li>key presses and releases,</li>
  <li>changes in focus,</li>
  <li>changes in keymaps…</li>
</ul>

<p>…all kinds of things. They give us a serious amount of control to pass along to the user.</p>

<h2 id="changes-to-the-testrigwindow-class">Changes to the TestRigWindow Class</h2>

<p>First, let’s look at the constructor:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">this</span><span class="p">()</span>
<span class="p">{</span>
	<span class="k">super</span><span class="p">(</span><span class="n">title</span><span class="p">);</span>
	<span class="n">addOnDestroy</span><span class="p">(</span><span class="k">delegate</span> <span class="kt">void</span><span class="p">(</span><span class="n">Widget</span> <span class="n">w</span><span class="p">)</span> <span class="p">{</span> <span class="n">quitApp</span><span class="p">();</span> <span class="p">}</span> <span class="p">);</span>
	
	<span class="n">addOnButtonPress</span><span class="p">(&amp;</span><span class="n">onMousePress</span><span class="p">);</span>
	
	<span class="n">showAll</span><span class="p">();</span>
	
<span class="p">}</span> <span class="c1">// this()</span>
</code></pre></div></div>

<p>The change of note is the call to <code class="language-plaintext highlighter-rouge">addOnButtonPress()</code>. This hooks our <code class="language-plaintext highlighter-rouge">onMousePress()</code> function to the <code class="language-plaintext highlighter-rouge">BUTTON_PRESS</code> event.</p>

<p>And that function looks like this:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="kt">bool</span> <span class="n">onMousePress</span><span class="p">(</span><span class="n">Event</span> <span class="n">event</span><span class="p">,</span> <span class="n">Widget</span> <span class="n">widget</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">bool</span> <span class="n">value</span> <span class="p">=</span> <span class="kc">false</span><span class="p">;</span>
	
	<span class="k">if</span><span class="p">(</span><span class="n">event</span><span class="p">.</span><span class="n">type</span> <span class="p">==</span> <span class="n">EventType</span><span class="p">.</span><span class="n">BUTTON_PRESS</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">GdkEventButton</span><span class="p">*</span> <span class="n">mouseEvent</span> <span class="p">=</span> <span class="n">event</span><span class="p">.</span><span class="n">button</span><span class="p">;</span>
		<span class="n">pressReport</span><span class="p">(</span><span class="n">mouseEvent</span><span class="p">.</span><span class="n">button</span><span class="p">);</span>
		<span class="n">value</span> <span class="p">=</span> <span class="kc">true</span><span class="p">;</span>
	<span class="p">}</span>

	<span class="k">return</span><span class="p">(</span><span class="n">value</span><span class="p">);</span>
	
<span class="p">}</span> <span class="c1">// onMousePress()</span>
</code></pre></div></div>

<p>Notice the function definition. We’re not returning a void, but a Boolean. And the arguments have changed, too. We’re passing in an event as well as the originating <code class="language-plaintext highlighter-rouge">Widget</code>, in this case it’s the Window underlying our <code class="language-plaintext highlighter-rouge">TestRigWindow</code> derivative.</p>

<p>We make sure we’ve actually got a new <code class="language-plaintext highlighter-rouge">Event</code> to play with, then dig into it to find its type. The only one we want to react to is <code class="language-plaintext highlighter-rouge">BUTTON_PRESS</code>. And which button was pressed? To find out, we dig a little deeper. Each <code class="language-plaintext highlighter-rouge">Event</code> carries with it a field identifying whatever bit of hardware was manipulated to cause the event.</p>

<p>All that stuff about a value that’s returned from this function has to do with signal chains which we covered in <a href="./0011-callback-chains.html">blog post #0011 Callback Chains</a>. Once the event has been handled, we tell <code class="language-plaintext highlighter-rouge">Main</code> we’re done handling signals and back away.</p>

<h2 id="but-wait-theres-more">But, wait, There’s more…</h2>

<p>You’ve likely noticed the call to pressReport() and here’s that function:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="n">pressReport</span><span class="p">(</span><span class="kt">uint</span> <span class="n">mouseButtonNumber</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">writeln</span><span class="p">(</span><span class="s">"Button # "</span><span class="p">,</span> <span class="n">mouseButtonNumber</span><span class="p">,</span> <span class="n">action</span><span class="p">);</span>

<span class="p">}</span> <span class="c1">// pressReport()</span>
</code></pre></div></div>

<p>I put this in here mostly to illustrate that mouse buttons are identified by <em>unsigned integers</em>, something we may need to know sometime down the road.</p>

<p>And that variable <em>action</em>? It’s a string defined at the top of <code class="language-plaintext highlighter-rouge">TestRigWindow</code>. Here is a list of the variables defined there:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">string</span> <span class="n">title</span> <span class="p">=</span> <span class="s">"Test Rig"</span><span class="p">;</span>
<span class="nb">string</span> <span class="n">buy</span> <span class="p">=</span> <span class="s">"Bye"</span><span class="p">;</span>
<span class="nb">string</span> <span class="n">action</span> <span class="p">=</span> <span class="s">" was pressed."</span><span class="p">;</span>
</code></pre></div></div>

<p>Nothing out of the ordinary except for the playful misspellings.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Next time, we’ll dig into some more mouse events. Until then, happy D-coding and may the <code class="language-plaintext highlighter-rouge">Widgets</code> be with you.</p>

<div class="blog-nav">
	<div style="float: left;">
		<a href="./0013-scrolled-layout.html">Previous: Scrolled Layout</a>
	</div>
	<div style="float: right;">
		<a href="./0015-enter-leave.html">Next: Entering and Leaving</a>
	</div>
</div>
<p>
	<h3></h3>
<div class="inpage-frame">
	<a href="https://github.com/sponsors/rontarrant">
		<BR>
		<BR>
		<B>Is this article useful? Educational? Entertaining, perhaps?</B>
		<BR>
		<figure class="left">
			<img src="../images/favorite_32.png" alt="Sponsorship heart" style="width: 32px; height: 32px;">
		</figure>
		You're free to accept or decline this invitation to become our newest sponsor.
	</a>
</div>
	<h4 class="comment-blurb"><B>Comments? Questions? Observations?</B></h4>
	<p>
		Did we miss a tidbit of information that would make this post even more informative? Let's talk about it in the comments.
	</p>
	<script src="https://utteranc.es/client.js"
		repo="rontarrant"
		issue-term="pathname"
		theme="github-light"
		crossorigin="anonymous"
		async>
	</script>
	<ul>
		<li> come on over to the <a href="https://forum.dlang.org/">D Language Forum</a> and look for one of the <i>gtkDcoding</i> announcement posts, </li>
		<li> drop by <a href="https://forum.gtkd.org/">the <i>GtkD Forum</i></a>,</li>
		<li> follow the link below to email me, or</li>
		<li> go to the	<a href="https://www.facebook.com">gtkDcoding Facebook page.</a></li>
	</ul>
</p>
<p> You can also subscribe <a href="/feed.xml">via RSS</a> so you won't miss anything. Thank you very much for dropping by.</p>
<p>&copy; Copyright 2025 Ron Tarrant </p>
</div>

	<a class="u-url" href="./0014-reacting-to-mouse-events.html" hidden></a>
</article>

      </div>
    </main><footer class="site-footer h-card">
  <data class="u-url" href="/"></data>

  <div class="wrapper">

    <h2 class="footer-heading">gtkDcoding</h2>

    <div class="footer-col-wrapper">
      <div class="footer-col footer-col-1">
        <ul class="contact-list">
          <li class="p-name">Ron Tarrant</li><li><a class="u-email" href="mailto:gtkDcoding@gmail.com">gtkDcoding@gmail.com</a></li></ul>
      </div>

      <div class="footer-col footer-col-2"><ul class="social-media-list"><li><a href="https://github.com/rontarrant"><svg class="svg-icon"><use xlink:href="../assets/minima-social-icons.svg#github"></use></svg> <span class="username">rontarrant</span></a></li></ul>
</div>

      <div class="footer-col footer-col-3">
        <p>Simple examples of how to use GtkD to build GUI applications.</p>
      </div>
    </div>

  </div>

</footer>
</body>

</html>
